package com.onlyxiahui.aware.extend.shardingsphere.algorithm;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import com.onlyxiahui.common.utils.base.util.time.LocalDateUtil;

/**
 * 月份分片<br>
 * Date 2019-08-26 10:57:11<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
public class MonthPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Comparable<?>> {

	@Override
	public String doSharding(
			final Collection<String> databaseNames,
			final PreciseShardingValue<Comparable<?>> shardingValue) {
		// 当前数据节点数量
		int size = databaseNames.size();
		if (size == 1) {
			return databaseNames.iterator().next();
		}
		Comparable<?> value = shardingValue.getValue();
		String text = getText(value);
		// 找到匹配的数据库名称并返回
		for (String databaseName : databaseNames) {
			if (eq(databaseName, text)) {
				return databaseName;
			}
		}
		throw new RuntimeException("数据分片异常");
	}

	boolean eq(String databaseName, String year) {
		return databaseName.endsWith(year);
	}

	public static String getText(Comparable<?> value) {
		String no = "";
		if (null != value) {
			if (value instanceof Date) {
				SimpleDateFormat dateFormat = new SimpleDateFormat("M");
				no = dateFormat.format(value);
			}
			if (value instanceof LocalDate) {
				no = LocalDateUtil.format((LocalDate) value, "M");
			}
			if (value instanceof LocalDateTime) {
				no = LocalDateUtil.format((LocalDateTime) value, "M");
			}
			if (value instanceof Timestamp) {
				SimpleDateFormat dateFormat = new SimpleDateFormat("M");
				no = dateFormat.format(value);
			}
			if (value instanceof String) {
				String dateTime = LocalDateUtil.allToDateTimeMillisecond(value.toString());
				no = LocalDateUtil.format(LocalDateUtil.stringToLocalDateTime(dateTime, LocalDateUtil.FORMAT_DATE_TIME_MILLISECOND), "yyyy");
			}
		}
		return no;
	}
}
